package org.jeecg.modules.demo.workflow.instanceState;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.SecurityUtils;
import org.flowable.engine.TaskService;
import org.flowable.engine.task.Comment;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.config.shiro.IgnoreAuth;
import org.jeecg.modules.demo.DailyWork.controller.DailyWorkController;
import org.jeecg.modules.demo.DailyWork.entity.DailyWork;
import org.jeecg.modules.demo.DailyWork.service.IDailyWorkService;
import org.jeecg.modules.demo.bean.vo.WflowModelDetailVo;
import org.jeecg.modules.demo.service.ModelGroupService;
import org.jeecg.modules.demo.utils.R;
import org.jeecg.modules.demo.workflow.bean.process.OrgUser;
import org.jeecg.modules.demo.workflow.bean.vo.ProcessStartParamsVo;
import org.jeecg.modules.demo.workflow.service.ProcessInstanceService;
import org.jeecg.modules.demo.workflow.service.ProcessTaskService;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.ISysUserRoleService;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.ResolverStyle;
import java.time.format.SignStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

import static org.jeecg.modules.demo.config.AsyncTaskTheadPoolConfig.executor;


@Tag(name = "日常工作流程状态")
@RestController
@RequestMapping("wflow/DaliyWorkDepartState")
public class DaliyWorkDepartState {
    @Autowired
    private IDailyWorkService dailyWorkService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ProcessTaskService taskService;
    @Autowired
    private TaskService taskServiceFlowable;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private ProcessInstanceService processService;

    @Autowired
    private ModelGroupService modelGroupService;

    @Autowired
    private DailyWorkController dailyWorkController;
    @Autowired
    private ISysDepartService sysDepartService;
    @Autowired
    private ISysUserRoleService sysUserRoleService;


    @AutoLog(value = "办理工作-部门更新")
    @Operation(summary = "办理工作-部门更新", description = "办理工作-部门更新")
    @IgnoreAuth
    @PostMapping("/setDepartState")
    public Object setRefuseStatus(@RequestParam String instanceId) {
        String userId = redisTemplate.opsForValue().get("userId").toString();
        String deptName = sysUserService.getDepNamesByUserId(userId);
        System.out.println("deptName = " + deptName);
        dailyWorkService.removeDeptByName(deptName, instanceId);
        //删除redis
        redisTemplate.delete("userId");
        return null;
    }

    @AutoLog(value = "办理工作-部门更新")
    @Operation(summary = "办理工作-部门更新", description = "办理工作-部门更新")
    @IgnoreAuth
    @PostMapping("/setDepartState1")
    public Object setRefuseStatus1(@RequestParam String instanceId) {
        Map<String, Object> task = taskService.getTaskById(instanceId);
        String userId = redisTemplate.opsForValue().get("userId").toString();
        String deptName = sysUserService.getDepNamesByUserId(userId);
        System.out.println("deptName = " + deptName);
        dailyWorkService.removeDeptByName(deptName, instanceId);
        //删除redis
        redisTemplate.delete("userId");
        return null;
    }


//    @Operation(summary = "日常工作信息导入excel", description = "日常工作信息导入excel")
//    @PostMapping(value = "/importWflow")
//    public Result<ProcessStartParamsVo> addwflow(MultipartFile file, String formId) throws Exception {
//        List<DailyWork> wflowDtoList = new ArrayList<>();
//        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

    /// /        System.out.println("loginUser = " + loginUser);
//        String realname = loginUser.getRealname();
//
//        // 读取Excel并解析数据（这部分还是单线程，因为读取文件本身不适合并行）
//        try (Workbook workbook = new XSSFWorkbook(file.getInputStream())) {
//            Sheet sheet = workbook.getSheetAt(0);
//            for (int i = 2; i <= sheet.getLastRowNum(); i++) { // 跳过标题行
//                System.out.println("sheet.getLastRowNum() = " + sheet.getLastRowNum());
//                Row row = sheet.getRow(i);
//                // 跳过空行
//                if (row == null) {
//                    continue;
//                }
//                // 检查关键单元格是否为空（这里以第一列作为关键判断依据）
//                Cell firstCell = row.getCell(0);
//                if (firstCell == null || getCellValueAsString(firstCell).trim().isEmpty()) {
//                    continue; // 如果关键单元格为空，视为空行跳过
//                }
//
//                // 1. 先创建基础DTO，设置公共属性
//                DailyWork baseWflowDto = new DailyWork();
//                baseWflowDto.setTaskSource(getCellValueAsString(row.getCell(0)));
//                baseWflowDto.setDescription(getCellValueAsString(row.getCell(1)));
//                baseWflowDto.setCompletionDeadline(getCellValueAsDate(row.getCell(2)));
//                baseWflowDto.setImplementationProgress(getCellValueAsString(row.getCell(3)));
//                baseWflowDto.setCompletionStatus(getCellValueAsString(row.getCell(4)));
//                baseWflowDto.setReviewer(realname); // 审核人是公共属性
//
//                // 2. 处理多部门（用逗号分隔）
//                String transactorsDeptStr = getCellValueAsString(row.getCell(5));
//                if (StringUtils.isNotBlank(transactorsDeptStr)) {
//                    // 拆分部门，处理可能的空格
//                    String[] deptArray = transactorsDeptStr.split(",");
//                    for (String dept : deptArray) {
//                        dept = dept.trim(); // 去除前后空格
//                        if (StringUtils.isBlank(dept)) {
//                            continue; // 跳过空部门
//                        }
//
//                        // 3. 为每个部门创建新的DTO，复制基础属性
//                        DailyWork wflowDto = new DailyWork();
//                        BeanUtils.copyProperties(baseWflowDto, wflowDto); // 复制公共属性
//
//                        // 4. 设置当前部门
//                        wflowDto.setTransactorsDept(dept);
//
//                        // 5. 根据当前部门查询办理人
//                        LambdaQueryWrapper<SysDepart> queryWrapper = new LambdaQueryWrapper<>();
//                        queryWrapper.eq(SysDepart::getDepartName, dept);
//                        SysDepart sysDepart = sysDepartService.getOne(queryWrapper);
//
//                        if (sysDepart != null) {
//                            LambdaQueryWrapper<SysUser> userQuery = new LambdaQueryWrapper<>();
//                            userQuery.eq(SysUser::getDepartIds, sysDepart.getId());
//                            List<SysUser> sysUserList = sysUserService.list(userQuery);
//
//                            for (SysUser user : sysUserList) {
//                                String roleId = sysUserRoleService.getRoleIdByUserId(user.getId());
//                                if ("1939932967836213250".equals(roleId)) {
//                                    wflowDto.setTransactors(user.getRealname());
//                                    break;
//                                }
//                            }
//                        } else {
//                            // 部门不存在时的处理（可选）
//                            wflowDto.setTransactors("未知办理人");
//                        }
//
//                        // 6. 添加到列表
//                        wflowDtoList.add(wflowDto);
//                        System.out.println("生成的wflowDto = " + wflowDto);
//                    }
//                } else {
//                    // 没有部门时的处理（可选）
//                    baseWflowDto.setTransactorsDept("");
//                    baseWflowDto.setTransactors("");
//                    wflowDtoList.add(baseWflowDto);
//                }
//            }
//        }
//
//        // 获取模型信息（只需一次，无需放在循环中）
//        WflowModelDetailVo model = (WflowModelDetailVo) modelGroupService.getModelById(formId);
//
//        // 创建线程池，核心线程数根据CPU核心数设定，这里使用CPU核心数 + 1
//        int corePoolSize = Runtime.getRuntime().availableProcessors() + 1;
//        ExecutorService executorService = new ThreadPoolExecutor(
//                corePoolSize,
//                corePoolSize * 2,
//                60L, TimeUnit.SECONDS,
//                new LinkedBlockingQueue<>(100),
//                new ThreadFactory() {
//                    private final AtomicInteger counter = new AtomicInteger(0);
//
//                    @Override
//                    public Thread newThread(Runnable r) {
//                        Thread thread = new Thread(r);
//                        thread.setName("import-wflow-thread-" + counter.incrementAndGet());
//                        thread.setDaemon(false); // 非守护线程
//                        return thread;
//                    }
//                },
//                new ThreadPoolExecutor.CallerRunsPolicy() // 当队列满时，让提交任务的线程执行任务，避免任务丢失
//        );
//
//        try {
//            // 存储所有异步任务，用于等待所有任务完成
//            List<CompletableFuture<Void>> futures = new ArrayList<>();
//           // 在创建 CompletableFuture 之前获取请求上下文
//            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//
//            // 并行处理每条记录
//            for (DailyWork wflowDto : wflowDtoList) {
//                // 使用CompletableFuture提交异步任务
//                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
//                    try {
//                        // 在子线程开始时设置请求上下文
//                        RequestContextHolder.setRequestAttributes(attributes, true);
//                        ProcessStartParamsVo processStartParamsVo = new ProcessStartParamsVo();
//                        processStartParamsVo.setDeptId("6d35e179cd814e3299bd588ea7daed3f");
//                        Map<String, Object> formData = new HashMap<>();
//                        formData.put(model.getFormItems().get(0).getId(), wflowDto.getTaskSource());
//                        formData.put(model.getFormItems().get(1).getId(), wflowDto.getDescription());
//                        formData.put(model.getFormItems().get(2).getId(), wflowDto.getCompletionDeadline());
//                        formData.put(model.getFormItems().get(3).getId(), wflowDto.getImplementationProgress());
//                        formData.put(model.getFormItems().get(4).getId(), wflowDto.getCompletionStatus());
//                        System.out.println("formData = " + formData);
//                        processStartParamsVo.setFormData(formData);
//
//                        Map<String, List<OrgUser>> processUsers = new HashMap<>();
//                        List<OrgUser> usersForNode1 = new ArrayList<>();
//                        String id1 = sysUserService.getUserIdByRealName(wflowDto.getReviewer());
//                        System.out.println("id1 = " + id1);
//                        List<OrgUser> usersForNode2 = new ArrayList<>();
//                        String id2 = sysUserService.getUserIdByRealName(wflowDto.getTransactors());
//                        System.out.println("id2 = " + id2);
//                        usersForNode1.add(new OrgUser(id1, wflowDto.getReviewer(), "", "user", true));
//                        usersForNode2.add(new OrgUser(id2, wflowDto.getTransactors(), "", "user", true));
//                        processUsers.put(model.getProcess().getChildren().getId(), usersForNode2);
//                        processUsers.put(model.getProcess().getChildren().getChildren().getId(), usersForNode1);
//                        processStartParamsVo.setProcessUsers(processUsers);
//                        System.out.println("processStartParamsVo = " + processStartParamsVo);
//
//                        // 启动流程
//                        String instanceId = processService.startProcess(model.getProcessDefId(), processStartParamsVo);
//                        wflowDto.setInstanceId(instanceId);
//
//                        // 保存记录
//                        dailyWorkController.add(wflowDto);
//                    } catch (Exception e) {
//                        System.err.println("处理记录时发生错误: " + e.getMessage());
//                        throw new CompletionException(e);
//                    } finally {
//                        // 清理上下文避免内存泄漏
//                        RequestContextHolder.resetRequestAttributes();
//                    }
//                }, executorService);
//
//                futures.add(future);
//            }
//
//            // 等待所有任务完成
//            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
//
//        } finally {
//            // 关闭线程池
//            executorService.shutdown();
//            // 等待线程池关闭
//            if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
//                executorService.shutdownNow();
//            }
//        }
//
//        return Result.ok();
//    }
    @Operation(summary = "日常工作信息导入excel", description = "日常工作信息导入excel")
    @PostMapping(value = "/importWflow")
    public Result<ProcessStartParamsVo> addwflow(MultipartFile file, String formId) throws Exception {
        List<DailyWork> wflowDtoList = new ArrayList<>();
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String realname = loginUser.getRealname();

        // 读取Excel并解析数据（处理合并单元格）
        try (Workbook workbook = new XSSFWorkbook(file.getInputStream())) {
            Sheet sheet = workbook.getSheetAt(0);
            // 关键：获取当前sheet中所有的合并单元格区域
            List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();

            for (int i = 2; i <= sheet.getLastRowNum(); i++) { // 跳过标题行
                System.out.println("sheet.getLastRowNum() = " + sheet.getLastRowNum());
                Row row = sheet.getRow(i);
                // 跳过空行
                if (row == null) {
                    continue;
                }
                // 检查关键单元格是否为空（处理合并单元格，以第一列作为关键判断依据）
                String firstCellValue = getMergedCellValue(sheet, mergedRegions, i, 0);
                if (firstCellValue == null || firstCellValue.trim().isEmpty()) {
                    continue; // 如果关键单元格为空，视为空行跳过
                }

                // 1. 先创建基础DTO，设置公共属性（使用合并单元格处理方法获取值）
                DailyWork baseWflowDto = new DailyWork();
                baseWflowDto.setTaskSource(getMergedCellValue(sheet, mergedRegions, i, 0));
                baseWflowDto.setDescription(getMergedCellValue(sheet, mergedRegions, i, 1));

                // 处理日期类型的合并单元格（先获取原始单元格再转换）
                Cell deadlineCell = getMergedCell(sheet, mergedRegions, i, 2);
//                baseWflowDto.setCompletionDeadline(deadlineCell != null ? getCellValueAsDate(deadlineCell) : null);
                baseWflowDto.setCompletionDeadline(parseDateCell(deadlineCell));
                baseWflowDto.setImplementationProgress(getMergedCellValue(sheet, mergedRegions, i, 3));
                baseWflowDto.setCompletionStatus(getMergedCellValue(sheet, mergedRegions, i, 4));
                baseWflowDto.setReviewer(realname); // 审核人是公共属性

                // 2. 处理多部门（用逗号分隔，同样处理合并单元格）
                String transactorsDeptStr = getMergedCellValue(sheet, mergedRegions, i, 5);
                if (StringUtils.isNotBlank(transactorsDeptStr)) {
                    // 拆分部门，处理可能的空格
                    String[] deptArray = transactorsDeptStr.split(",");
                    for (String dept : deptArray) {
                        dept = dept.trim(); // 去除前后空格
                        if (StringUtils.isBlank(dept)) {
                            continue; // 跳过空部门
                        }

                        // 3. 为每个部门创建新的DTO，复制基础属性
                        DailyWork wflowDto = new DailyWork();
                        BeanUtils.copyProperties(baseWflowDto, wflowDto); // 复制公共属性

                        // 4. 设置当前部门
                        wflowDto.setTransactorsDept(dept);

                        // 5. 根据当前部门查询办理人
                        LambdaQueryWrapper<SysDepart> queryWrapper = new LambdaQueryWrapper<>();
                        queryWrapper.eq(SysDepart::getDepartName, dept);
                        SysDepart sysDepart = sysDepartService.getOne(queryWrapper);

                        if (sysDepart != null) {
                            LambdaQueryWrapper<SysUser> userQuery = new LambdaQueryWrapper<>();
                            userQuery.eq(SysUser::getDepartIds, sysDepart.getId());
                            List<SysUser> sysUserList = sysUserService.list(userQuery);

                            for (SysUser user : sysUserList) {
                                String roleId = sysUserRoleService.getRoleIdByUserId(user.getId());
                                if ("1939932967836213250".equals(roleId)) {
                                    wflowDto.setTransactors(user.getRealname());
                                    break;
                                }
                            }
                        } else {
                            // 部门不存在时的处理（可选）
                            wflowDto.setTransactors("未知办理人");
                        }

                        // 6. 添加到列表
                        wflowDtoList.add(wflowDto);
                        System.out.println("生成的wflowDto = " + wflowDto);
                    }
                } else {
                    // 没有部门时的处理（可选）
                    baseWflowDto.setTransactorsDept("");
                    baseWflowDto.setTransactors("");
                    wflowDtoList.add(baseWflowDto);
                }
            }
        }

        // 获取模型信息（只需一次，无需放在循环中）
        WflowModelDetailVo model = (WflowModelDetailVo) modelGroupService.getModelById(formId);

        // 创建线程池，核心线程数根据CPU核心数设定，这里使用CPU核心数 + 1
        int corePoolSize = Runtime.getRuntime().availableProcessors() + 1;
        ExecutorService executorService = new ThreadPoolExecutor(
                corePoolSize,
                corePoolSize * 2,
                60L, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(100),
                new ThreadFactory() {
                    private final AtomicInteger counter = new AtomicInteger(0);

                    @Override
                    public Thread newThread(Runnable r) {
                        Thread thread = new Thread(r);
                        thread.setName("import-wflow-thread-" + counter.incrementAndGet());
                        thread.setDaemon(false); // 非守护线程
                        return thread;
                    }
                },
                new ThreadPoolExecutor.CallerRunsPolicy() // 当队列满时，让提交任务的线程执行任务，避免任务丢失
        );

        try {
            // 存储所有异步任务，用于等待所有任务完成
            List<CompletableFuture<Void>> futures = new ArrayList<>();
// 获取当前请求上下文
            RequestAttributes attributes = RequestContextHolder.getRequestAttributes();

            // 并行处理每条记录
            for (DailyWork wflowDto : wflowDtoList) {
                // 使用CompletableFuture提交异步任务
                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                    try {
                        if (wflowDto.getCompletionStatus().equals("已完成")) {
                            // 在子线程开始时设置请求上下文
                            RequestContextHolder.setRequestAttributes(attributes, true);
                            dailyWorkController.add(wflowDto);
                        } else {

                            // 在子线程开始时设置请求上下文
                            RequestContextHolder.setRequestAttributes(attributes, true);
                            ProcessStartParamsVo processStartParamsVo = new ProcessStartParamsVo();
                            processStartParamsVo.setDeptId("6d35e179cd814e3299bd588ea7daed3f");
                            Map<String, Object> formData = new HashMap<>();
                            formData.put(model.getFormItems().get(0).getId(), wflowDto.getTaskSource());
                            formData.put(model.getFormItems().get(1).getId(), wflowDto.getDescription());
                            formData.put(model.getFormItems().get(2).getId(), wflowDto.getCompletionDeadline());
                            formData.put(model.getFormItems().get(3).getId(), wflowDto.getImplementationProgress());
                            formData.put(model.getFormItems().get(4).getId(), wflowDto.getCompletionStatus());
                            System.out.println("formData = " + formData);
                            processStartParamsVo.setFormData(formData);

                            Map<String, List<OrgUser>> processUsers = new HashMap<>();
                            List<OrgUser> usersForNode1 = new ArrayList<>();
                            String id1 = sysUserService.getUserIdByRealName(wflowDto.getReviewer());
                            System.out.println("id1 = " + id1);
                            List<OrgUser> usersForNode2 = new ArrayList<>();
                            String id2 = sysUserService.getUserIdByRealName(wflowDto.getTransactors());
                            System.out.println("id2 = " + id2);
                            usersForNode1.add(new OrgUser(id1, wflowDto.getReviewer(), "", "user", true));
                            usersForNode2.add(new OrgUser(id2, wflowDto.getTransactors(), "", "user", true));
                            processUsers.put(model.getProcess().getChildren().getId(), usersForNode2);
                            processUsers.put(model.getProcess().getChildren().getChildren().getId(), usersForNode1);
                            processStartParamsVo.setProcessUsers(processUsers);
                            System.out.println("processStartParamsVo = " + processStartParamsVo);

                            // 启动流程
                            String instanceId = processService.startProcess(model.getProcessDefId(), processStartParamsVo);
                            wflowDto.setInstanceId(instanceId);

                            // 保存记录
                            dailyWorkController.add(wflowDto);
                        }
                    } catch (Exception e) {
                        System.err.println("处理记录时发生错误: " + e.getMessage());
                        throw new CompletionException(e);
                    } finally {
                        // 清理上下文避免内存泄漏
                        RequestContextHolder.resetRequestAttributes();
                    }
                }, executorService);

                futures.add(future);
            }
            // 等待所有任务完成
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

        } finally {
            // 关闭线程池
            executorService.shutdown();
            // 等待线程池关闭
            if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
                executorService.shutdownNow();
            }
        }

        return Result.ok();
    }

    /**
     * 核心工具方法：获取合并单元格的值（若为普通单元格则直接返回值）
     *
     * @param sheet         工作表
     * @param mergedRegions 所有合并区域列表
     * @param row           目标行号
     * @param col           目标列号
     * @return 单元格的字符串值
     */
    private String getMergedCellValue(Sheet sheet, List<CellRangeAddress> mergedRegions, int row, int col) {
        Cell targetCell = getMergedCell(sheet, mergedRegions, row, col);
        return targetCell != null ? getCellValueAsString(targetCell) : "";
    }

    /**
     * 核心工具方法：获取合并区域对应的实际单元格（合并区域返回首单元格，普通单元格返回自身）
     *
     * @param sheet         工作表
     * @param mergedRegions 所有合并区域列表
     * @param row           目标行号
     * @param col           目标列号
     * @return 实际的单元格对象
     */
    private Cell getMergedCell(Sheet sheet, List<CellRangeAddress> mergedRegions, int row, int col) {
        // 遍历所有合并区域，判断当前行列是否在合并区域内
        for (CellRangeAddress mergedRegion : mergedRegions) {
            if (mergedRegion.isInRange(row, col)) {
                // 合并区域的首行首列单元格存储了值，返回该单元格
                return sheet.getRow(mergedRegion.getFirstRow()).getCell(mergedRegion.getFirstColumn());
            }
        }
        // 非合并单元格，直接返回当前行列的单元格
        Row currentRow = sheet.getRow(row);
        return currentRow != null ? currentRow.getCell(col) : null;
    }

    /**
     * 工具方法：将单元格值转换为字符串（处理各种单元格类型）
     *
     * @param cell 单元格对象
     * @return 字符串格式的值
     */
    private String getCellValueAsString(Cell cell) {
        if (cell == null) {
            return "";
        }
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue().trim();
            case NUMERIC:
                // 处理日期格式的数字
                if (DateUtil.isCellDateFormatted(cell)) {
                    return new SimpleDateFormat("yyyy-MM-dd").format(cell.getDateCellValue());
                } else {
                    // 处理普通数字，避免科学计数法
                    double numericValue = cell.getNumericCellValue();
                    if (numericValue == (long) numericValue) {
                        return String.valueOf((long) numericValue);
                    } else {
                        return String.valueOf(numericValue);
                    }
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                // 解析公式结果
                Cell evaluatedCell = new XSSFFormulaEvaluator((XSSFWorkbook) cell.getSheet().getWorkbook()).evaluateInCell(cell);
                return getCellValueAsString(evaluatedCell);
            default:
                return "";
        }
    }

    private Date parseDateCell(Cell cell) {
        if (cell == null) {
            System.err.println("解析日期失败：单元格为空");
            return null;
        }

        try {
            CellType cellType = cell.getCellType();
            System.out.println("cellType = " + cellType);

            // 1. 处理数字类型（可能是Excel原生日期，也可能是普通数字）
            if (cellType == CellType.NUMERIC) {
                // 尝试将其作为日期来解析
                // 即使格式是自定义的 "yyyy年m月d日"，cell.getDateCellValue() 也能正确获取日期
                Date excelDate = cell.getDateCellValue();

                // （可选但推荐）增加一个合理性检查，避免把普通数字（如123）解析成1900年的日期
                // Excel的日期起始于1900年，我们可以认为1970年之后的日期才是有效的业务日期
                if (excelDate.after(new Date(0))) { // new Date(0) 是 1970-01-01 00:00:00 UTC
                    System.out.printf("解析 Excel 数字为日期成功（自定义格式）：单元格内容（数字）-> 日期：%s%n", excelDate);
                    return excelDate;
                } else {
                    // 如果日期太早，说明它可能不是一个有效的业务日期，而是一个普通数字
                    System.err.println("解析日期失败：单元格是数字，但值太小，不被视为有效日期。");
                    // 你可以在这里决定是返回null，还是抛出异常，或者将其作为数字处理
                    return null;
                }
            }
            // 2. 处理字符串类型的日期
            else if (cellType == CellType.STRING) {
                String value = cell.getStringCellValue().trim();
                if (value.isEmpty()) {
                    System.err.println("解析日期失败：字符串单元格内容为空");
                    return null;
                }

//            if ("持续推进".equals(value)) {
//                LocalDateTime endOfYear = LocalDateTime.now()
//                        .plusYears(1)
//                        .withDayOfYear(1)
//                        .minusSeconds(1);
//                Date resultDate = Date.from(endOfYear.atZone(ZoneId.systemDefault()).toInstant());
//                System.out.printf("解析“持续推进”成功：默认日期 -> %s%n", resultDate);
//                return resultDate;
//            }
                if ("持续推进".equals(value)) {
                    // 1. 获取当前日期和时间
                    LocalDateTime now = LocalDateTime.now();

                    // 2. 使用 TemporalAdjusters 将日期调整到今年的最后一天
                    //    然后使用 withHour, withMinute, withSecond, withNano 将时间设置为 00:00:00
                    LocalDateTime endOfYearStart = now.with(TemporalAdjusters.lastDayOfYear())
                            .withHour(0)
                            .withMinute(0)
                            .withSecond(0)
                            .withNano(0);

                    // 或者使用更简洁的 atStartOfDay()
                    // LocalDateTime endOfYearStart = now.with(TemporalAdjusters.lastDayOfYear()).toLocalDate().atStartOfDay();

                    // 3. 转换为 Date 对象 (如果必须返回 Date)
                    Date resultDate = Date.from(endOfYearStart.atZone(ZoneId.systemDefault()).toInstant());

                    System.out.printf("解析“持续推进”成功：默认日期 -> %s%n", resultDate);
                    return resultDate;
                }

//            // --- 重要修改：增加对 "yyyy年MM月dd日" 格式的支持 ---
//            // 定义一个包含多种可能格式的格式化器
//            DateTimeFormatter formatter = new DateTimeFormatterBuilder()
//                    // 尝试解析 "yyyy年MM月dd日" 格式
//                    .appendOptional(DateTimeFormatter.ofPattern("yyyy年MM月dd日"))
//                    // 尝试解析 "yyyy年M月d日" 格式 (月份和日期是一位数)
//                    .appendOptional(DateTimeFormatter.ofPattern("yyyy年M月d日"))
//                    // 尝试解析 "yyyy/MM/dd" 或 "yyyy-MM-dd" 格式
//                    .appendOptional(new DateTimeFormatterBuilder()
//                            .appendPattern("yyyy")
//                            .appendPattern("[/-]")
//                            .appendPattern("MM")
//                            .appendPattern("[/-]")
//                            .appendPattern("dd")
//                            .optionalStart()
//                            .appendLiteral(' ')
//                            .appendPattern("HH:mm:ss")
//                            .optionalEnd()
//                            .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
//                            .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
//                            .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
//                            .toFormatter())
//                    .toFormatter(Locale.CHINA) // 使用中国Locale，确保对中文的正确处理
//                    .withResolverStyle(ResolverStyle.STRICT);
                // 定义一个包含多种可能格式的格式化器
                DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                        // 格式一：带年月日的中文格式 (月份和日期为1或2位数都可以)
                        .optionalStart()
                        .appendValue(ChronoField.YEAR, 4)
                        .appendLiteral('年')
                        .appendValue(ChronoField.MONTH_OF_YEAR, 1, 2, SignStyle.NOT_NEGATIVE)
                        .appendLiteral('月')
                        .appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NOT_NEGATIVE)
                        .appendLiteral('日')
                        .optionalEnd()
                        // 格式二：标准的 yyyy-MM-dd 或 yyyy/MM/dd 格式 (可带可选时间)
                        .optionalStart()
                        .appendPattern("yyyy")
                        .appendPattern("[/-]")
                        .appendPattern("MM")
                        .appendPattern("[/-]")
                        .appendPattern("dd")
                        .optionalStart()
                        .appendLiteral(' ')
                        .appendPattern("HH:mm:ss")
                        .optionalEnd()
                        .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
                        .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
                        .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
                        .optionalEnd()
                        .toFormatter(Locale.CHINA)
                        .withResolverStyle(ResolverStyle.STRICT);

                LocalDateTime parsedDateTime = LocalDateTime.parse(value, formatter);
                Date resultDate = Date.from(parsedDateTime.atZone(ZoneId.systemDefault()).toInstant());
                System.out.printf("解析字符串日期成功：%s -> %s%n", value, resultDate);
                return resultDate;
            }

            System.err.printf("解析日期失败：不支持的单元格类型 -> %s%n", cellType);
        } catch (Exception e) {
            String cellContent = "";
            try {
                // 如果是数字类型，获取其数字值作为内容
                if (cell.getCellType() == CellType.NUMERIC) {
                    cellContent = String.valueOf(cell.getNumericCellValue());
                } else {
                    cellContent = cell.getStringCellValue();
                }
            } catch (Exception e1) {
                // ignore
            }
            System.err.printf("解析日期失败：单元格内容='%s'，错误信息：%s%n", cellContent, e.getMessage());
        }

        return null;
    }

    /**
     * 流程通过时监听器调用接口
     * 日常工作-通过状态
     *
     * @param instanceId 流程实例ID
     */
    @AutoLog(value = "日常工作-通过状态")
    @Operation(summary = "日常工作-通过状态", description = "日常工作-通过状态")
    @PostMapping("setPassState")
    public Object setPassStatus(@RequestParam String instanceId) {
        String result = "未完成";

        String s = "";
        String personName = "";
        String parentId = "";
        Map<String, Object> task = taskService.getTaskById(instanceId);
        System.out.println("task = " + task);
        // 使用线程池执行异步任务
        String finalParentId = parentId;
        executor.execute(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            List<org.flowable.engine.task.Comment> processInstanceComments = taskServiceFlowable.getProcessInstanceComments(instanceId);
            String actComment = "";
            Date time = null;
            String text = "";
            String concatenatedUrls = null;
            System.out.println("processInstanceComments = " + processInstanceComments);
            if (!processInstanceComments.isEmpty()) {
                for (Comment comment : processInstanceComments) {
                    System.out.println("acr1: " + comment.toString());
                    String id = (String) task.get("id");
                    if (id.equals(comment.getTaskId())) {
                        actComment = comment.getFullMessage();
                        time = comment.getTime();
                    }
                }

                System.out.println("act:" + actComment);
                // 解析 JSON 字符串
                JSONObject jsonObject = JSON.parseObject(actComment);

                // 获取 attachments 数组
                JSONArray attachments = jsonObject.getJSONArray("attachments");

                List<String> urlList = new ArrayList<>();
                // 提取两个 url
                for (int i = 0; i < attachments.size(); i++) {
                    JSONObject attachment = attachments.getJSONObject(i);
                    String url = attachment.getString("url");
                    System.out.println("URL " + (i + 1) + ": " + url);
                    urlList.add(url);
                }
                concatenatedUrls = String.join(",", urlList);
                System.out.println("Concatenated URLs: " + concatenatedUrls);

                // 获取 text 内容
                text = jsonObject.getString("text");
                System.out.println("Text: " + text);

            } else {
                text = "流程被拒绝";
                time = new Date();
            }
            String realname = (String) task.get("realname");
            String name1 = (String) task.get("name");
        });

        if (task != null) {
            s = (String) task.get("taskDefinitionKey");
            System.out.println("s = " + s);
            personName = (String) task.get("name");
            if ("审核人".equals(personName)) {
                result = "已完成";
            }
            System.out.println("personName = " + personName);
        }

        DailyWork dailyWork = dailyWorkService.getOne(new LambdaQueryWrapper<DailyWork>().
                eq(DailyWork::getInstanceId, instanceId));
        dailyWork.setCompletionStatus(result);
        dailyWorkService.updateById(dailyWork);

        return R.ok(result);
    }


//    private String getCellValueAsString(Cell cell) {
//        if (cell == null) return "";
//        switch (cell.getCellType()) {
//            case STRING:
//                return cell.getStringCellValue();
//            case NUMERIC:
//                if (DateUtil.isCellDateFormatted(cell)) { // 判断是否是日期格式
//                    // 创建一个日期格式化对象
//                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//                    // 返回格式化后的日期字符串
//                    return dateFormat.format(cell.getDateCellValue());
//                } else {
//                    // 非日期的数值直接返回其整数部分的字符串形式
//                    return String.valueOf((int) cell.getNumericCellValue());
//                }
//            default:
//                return "";
//        }
//    }
//    // 新增一个返回Date类型的方法
//    private Date getCellValueAsDate(Cell cell) {
//        if (cell == null) return null;
//        if (cell.getCellType() == CellType.NUMERIC && DateUtil.isCellDateFormatted(cell)) {
//            return cell.getDateCellValue();
//        }
//        // 如果单元格不是日期格式但包含日期字符串，可以在这里添加解析逻辑
//        if (cell.getCellType() == CellType.STRING) {
//            try {
//                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//                return sdf.parse(cell.getStringCellValue());
//            } catch (ParseException e) {
//                // 可以根据实际格式调整或添加更多格式尝试
//                return null;
//            }
//        }
//        return null;
//    }

}
